import sys
import re
import traceback

from paste.request import parse_formvars

import pyframe

from pyframe.xml.helper import Helper
from pyframe.exceptions.document_file_not_found_exception import DocumentFileNotFoundException
from pyframe.exceptions.xml_serializable_exception import XmlSerializableException
from pyframe.block import Block

class Engine(object):

	def __init__(self, environ, response):

		self.__environ = environ;
		self.__request = parse_formvars(environ)
		self.__status = '200'
		self.__contentType = 'text/plain'
		self.__response = response
		self.__output = []
		self.__document = None
		self.__template = None
		self.__xmlHelper = Helper()

		environ['paste.registry'].register(pyframe.instance, self)

	def run(self):

		try:

			self.__document = self.__xmlHelper.createDocumentFromFile(
				pyframe.getFrontDirectory() + self.__environ['PATH_INFO'].lstrip('/')
				)
			self.__processDocument()
			self.__write(self.__processTemplate())

		except DocumentFileNotFoundException:

			if('paste.recursive.old_path_info' in self.__environ and
				self.__environ['PATH_INFO'] in self.__environ['paste.recursive.old_path_info']):
				self.__setStatus('500')
				self.__write('404')
			else:
				self.__setStatus('404')

		except Exception, instance:

			type, value, lastTraceback = sys.exc_info()
			self.__write("\n".join(traceback.format_exception(type, value, lastTraceback)))

		self.__response(self.__status, [('Content-Type', self.__contentType)])

		return "".join(self.__output)

	def __processDocument(self):

		self.__document.xinclude()

		templateFileName = self.__xmlHelper.getTemplateFileNameFromDocument(self.__document)

		if(templateFileName):
			self._template = pyframe.getFrontDirectory() + templateFileName

		""" for event, node in self._document:

			if(event == 'pi' and node.target == 'xsl-stylesheet'):
				matches = re.search(r'href="(.+)"', node.text)
				if(matches):
					self._template = self._frontDirectory + matches.group(1)

			elif(node.tag == '{%s}block'  % NAME_SPACE and node.get('method')):
				self._processBlockNode(node)
		"""
		for blockNode in self.__document.findall('{%s}block' % pyframe.NAME_SPACE):
			self._processBlockNode(blockNode);

	def _processBlockNode(self, node):

		block = Block(node);

		try:
			self.__xmlHelper.replaceNodeByString(node, block.process())

		except XmlSerializableException, instance:
			self.__xmlHelper.replaceChildrenByString(node, instance.toXML())

		#except Exception, instance:
			#self._xmlHelper.replaceChildrenByString(node, XmlSerializableException(instance.message).toXML())

	def __processTemplate(self):

		if(self.__template):

			result = self.__xmlHelper.processXSLT(self.__document, self.__template)
			if(result['output'] == 'html'):
				self.__setContentType('text/html')
			elif(result['output'] == 'xml'):
				self.__setContentType('text/xml')
			else:
				self.__setContentType('text/plain')
			return str(result['document'])

		self.__setContentType('text/xml')
		return self.__xmlHelper.serializeNode(self.__document)

	def __setContentType(self, value):
		self.__contentType = value

	def __setStatus(self, value):
		self.__status = value

	def __write(self, value):
		self.__output.append(value)

	def getRequest(self):
		return self.__request

	def getEnviron(self):
		return self.__environ

	def getXmlHelper(self):
		return self.__xmlHelper

